在昨天的文章中,我們對如何使用 Stream 這個 Feature 的使用方式做了一些說明。
事實上,除了使用官方預提供的 Stream 以外,我們仍然可以自定義 Stream 的實現。
舉例來說,我們甚至可以實現 dropbox:// 或 s3:// 這樣的 stream 然後加以利用(不過大多數的 Object Storage 都是提供 RESTful API 或是 SDK 去存取,罕有人會親自去實現 stream)
PHP 官方有提供一個範例,讓人可以參考如何實現自定義的 Stream Wrapper。
因為程式碼已經相當完整,所以這邊不重新複製貼上,僅針對程式碼本身做一些說明。
stream_openstream_open(string $path, string $mode, int $options, ?string &$opened_path): bool
用於開啟 stream,假設已經實現 dropbox:// 且調用 fopen('dropbox://file.txt', 'r')
$path === 'dropbox://file.txt'
$mode === 'r'
$options === 0
$opened_path === 'dropbox://file.txt'
$options 具有兩個 flag:STREAM_USE_PATH 及 STREAM_REPORT_ERRORS
$opened_path 表示如果成功將 $path 指定的資源打開,會回傳與 $path 相同的內容,可用於檢測資源是否成功開啟。
註:
$mode是可以自由定義的,不一定侷限於 file stream 的形式。
stream_readstream_read(int $count): mixed
用於讀取指定的 stream,通常 $count 指的是「第幾個 byte」,不過這邊的定義可由實現者自行決定。
stream_writestream_write(mixed $data): int
將 $data 寫入目前 stream 的所在位置,並且回傳成功寫入的資料長度.
stream_tellstream_tell(): int
回傳目前 Stream 的所在位置,部份 Stream 都是可以任意操作位置的,此時利用 stream_tell 取得目前所在位置。
stream_eofstream_eof(): bool
確認目前的 Stream 是否已經到盡頭,EOF 表示 End Of File,不過在 Stream 上依然能夠套用這樣的邏輯。
stream_seekstream_seek(int $offset, int $whence): bool
用於在 Stream 中自由移動,$offset 表示移動「多少」資料(通常指的是 byte 數),$whence 則是來自於 C 語言的 fseek()。
$whence 有三種可能的值:SEEK_SET, SEEK_CUR 與 SEEK_END,分別表示「從資料的開頭」、「從目前的位置」及「從資料的尾端」(不過你依然可以自由定義其它的可能值)
stream_metadatastream_metadata(string $path, string $option, mixed $var): bool
用於變更目前使用 Stream 的 Metadata,通常是由以下函式呼叫時會使用的
touch()
chmod()
chown()
chgrp()
$path 與 stream_open 相同。
$option 可能是下列一個值:STREAM_META_TOUCH, STREAM_META_OWNER_NAME, STREAM_META_OWNER, STREAM_META_GROUP_NAME, STREAM_META_GROUP 及 STREAM_META_ACCESS
$var 根據 $option 的不同而有不同的值。
事實上, Stream 的實作時還是相當以 File 為本位進行思考,畢竟在 Linux 「萬物皆檔案」的思想中,Stream 也是一種檔案流。
通常不太會自行實現網路服務相關的 Stream,僅會針對一些比較底層的服務(如 NFS)設計一些 stream 來使用,而這在實務上比較罕見(通常都是倚賴 RESTful API 去存取較多)